package model

import (
	"errors"
	"strings"

	"github.com/hwcer/cosgo/schema"
	"github.com/hwcer/cosgo/values"
	"github.com/hwcer/cosmo"
	"github.com/hwcer/logger"
	"github.com/hwcer/updater"
	"github.com/hwcer/updater/dataset"
	"github.com/hwcer/updater/operator"
)

func init() {
	Register(&Items{})
}

type Items struct {
	Model `bson:"inline"`
	//Unit   `bson:"inline"`
	//Chip   `bson:"inline"`
	Bag    int32         `json:"bag" bson:"bag"`
	Value  int64         `bson:"val" json:"val,omitempty"` //当前数量
	Expire int64         `bson:"ttl" json:"ttl,omitempty"` //过期时间
	Attach values.Values `bson:"att" json:"att,omitempty"` //通用字段,只允许基本类型，其他类型使用 Attach.Marshal Attach.Unmarshal存取
	//egg
	//Use     string `bson:"use" json:"use"`         //是否在被孵化
	SumTime int64 `bson:"sumTime" json:"sumTime,omitempty"` //孵化时间
	//eggTask
	Condition string `bson:"condition" json:"condition,omitempty"` //条件
	EndTime   int64  `bson:"endTime" json:"endTime,omitempty"`     //任务到期时间.毫秒
	//build
	Skin int32 `bson:"skin" json:"skin,omitempty"` ////皮肤
	//ticket
	LastGetTime int64 `bson:"lastGetTime" json:"lastGetTime,omitempty"` ////最后更新时间
	//装备 英雄 egg build
	//Use string `json:"use,omitempty" bson:"use"` //是否被使用
	//Lv  int32  `json:"lv,omitempty" bson:"lv"`   //等级
}

func (this *Items) Get(k string) (any, bool) {
	if i := strings.Index(k, "."); i > 0 && k[0:i] == "att" {
		return this.Attach.Get(k[i+1:]), true
	}
	switch k {
	case "Value", "val":
		return this.Value, true
	case "Expire", "ttl":
		return this.Expire, true
	case "Attach", "att":
		return this.Attach, true
	default:
		return this.Model.Get(k)
	}
}

func (this *Items) Set(k string, v any) (any, bool) {
	if i := strings.Index(k, "."); i > 0 && k[0:i] == "att" {
		return this.marshal(k[i+1:], v), true
	}
	switch k {
	case "Value", "val":
		this.Value = dataset.ParseInt64(v)
	case "Expire", "ttl":
		this.Expire = dataset.ParseInt64(v)
	case "Attach", "att":
		this.Attach = v.(values.Values)
	default:
		return this.Model.Set(k, v)
	}
	return v, true
}

func (this *Items) marshal(k string, v any) any {
	if r, err := this.Attach.Marshal(k, v); err != nil {
		logger.Error(err)
		return dataset.Update{} //返回空Update不会向数据库写入错误数据
	} else {
		return r
	}
}

func (this *Items) Copy() *Items {
	i := this.Clone()
	return i.(*Items)
}

// clone 复制对象,可以将NEW新对象与SET操作解绑

func (this *Items) Schema() *schema.Schema {
	sch, _ := schema.Parse(this)
	return sch
}
func (this *Items) GetValueJSName() string {
	return "val"
}

func (this *Items) Clone() any {
	r := *this
	r.Attach = this.Attach.Clone()
	return &r
}

func (this *Items) Upsert(u *updater.Updater, op *operator.Operator) bool {
	return false
}

func (this *Items) Getter(u *updater.Updater, coll *dataset.Collection, keys []string) (err error) {
	uid := u.Uid()
	if uid == "" {
		return errors.New("Items.Getter uid not found")
	}
	//var rows []*Items
	tx := db.Model(this).Where("uid = ?", uid)
	tx = tx.Omit("update")
	if len(keys) > 0 {
		tx = tx.Where("_id IN ?", keys)
	}
	tx.Range(func(cursor cosmo.Cursor) bool {
		v := &Items{}
		if err = cursor.Decode(v); err != nil {
			return false
		}
		coll.Receive(v.OID, v)
		return true
	})

	return
}
func (this *Items) Setter(u *updater.Updater, bw dataset.BulkWrite) error {
	return bw.Submit()
}

func (this *Items) BulkWrite(u *updater.Updater) dataset.BulkWrite {
	bw := NewBulkWrite(this)
	return bw
}

// TableName 数据库表名
func (*Items) TableName() string {
	return "items"
}

// TableOrder 初始化时的排序，DESC
func (*Items) TableOrder() int32 {
	return 99
}
